﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using GrainManage.Model;
using System.Windows;

namespace GrainManage
{
    public sealed class SafeInvoke
    {
        public static void TryBeginInvoke(Action tryAction, Action finallyAction, Action callBack, Dispatcher dispatcher)
        {
            Action newAction = () =>
            {
                try
                {
                    tryAction();
                    if (callBack != null) { BeginInvokeUI(callBack, dispatcher); }
                }
                catch (Exception e) { ShowStatus(e.Message, "Local Exception", dispatcher); }
                finally { if (finallyAction != null) { BeginInvokeUI(finallyAction, dispatcher); } }
            };
            //newAction.BeginInvoke((ar) => { if (callBack != null) BeginInvokeUI(callBack); }, null);
            newAction.BeginInvoke(null, null);
        }

        public static void TryBeginInvoke<T>(Func<T> func, Action<T> finallyAction, Action<T> callBack, Dispatcher dispatcher)
        {
            #region MyRegion
            //func.BeginInvoke((ar) =>
            //{
            //    Func<T> action = (ar as System.Runtime.Remoting.Messaging.AsyncResult).AsyncDelegate as Func<T>;
            //    T result = action.EndInvoke(ar);
            //    BeginInvokeUI(() => callBack(result));
            //}, null);
            #endregion

            Action newAction = () =>
            {
                T result = default(T);
                try
                {
                    result = func.Invoke();
                    BeginInvokeUI(() => callBack(result), dispatcher);
                }
                catch (Exception e) { ShowStatus(e.Message, "Local Exception", dispatcher); }
                finally { if (finallyAction != null) { BeginInvokeUI(() => finallyAction(result), dispatcher); } }
            };
            newAction.BeginInvoke(null, null);
        }

        public static void InvokeUI(Action uiAction, Dispatcher dispatcher)
        {
            dispatcher.Invoke(uiAction, DispatcherPriority.Background);
        }

        public static void BeginInvokeUI(Action uiAction, Dispatcher dispatcher)
        {
            dispatcher.BeginInvoke(uiAction, DispatcherPriority.Background);
        }

        public static void ShowStatus(int statusCode, string message, Dispatcher dispatcher)
        {

            Action action = () =>
            {
                try
                {
                    if (string.IsNullOrEmpty(message))
                    {
                        var helper = new GrainManage.Tools.StatusHelper();
                        message = helper.GetMessage(statusCode);
                        ShowStatus(message, "From Server, Status Code: " + statusCode, dispatcher);
                    }
                }
                catch (Exception e)
                {
                    message = e.Message;
                    ShowStatus(message, "From Local, GetMessage Failed", dispatcher);
                    Log.Write("ShowStatus:", e);
                }
            };

            action.BeginInvoke(null, null);
        }

        public static void ShowStatus(string message, string caption, Dispatcher dispatcher)
        {
            Action showAction = () => MessageBox.Show(message, caption, MessageBoxButton.OK, MessageBoxImage.Error);
            dispatcher.BeginInvoke(showAction, System.Windows.Threading.DispatcherPriority.Background);
        }
    }
}
